/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huawei.housekeeper.common.filter;

import com.huawei.housekeeper.common.exception.Assert;
import com.huawei.housekeeper.common.properties.ResourcesExcluderProperties;
import com.huawei.housekeeper.common.utils.JwtTokenUtil;
import com.huawei.housekeeper.common.utils.RegexMatchUtil;

import com.google.common.net.HttpHeaders;

import lombok.extern.log4j.Log4j2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Arrays;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 租户标识过滤器
 *
 * @author lWX1128557
 * @since 2022-04-01
 */
@Component
@Log4j2
public class VerifyDomainFilter implements Filter, Ordered {

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private ResourcesExcluderProperties resourcesExcluderProperties;


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws ServletException, IOException {

            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            String[] excludedUris = resourcesExcluderProperties.getExcludedUris();

            String uri = request.getRequestURI();
            log.info("uri: {} , excludedUris: {}", uri, excludedUris);

            for (String excUrl : Arrays.asList(excludedUris)) {
                String rex = RegexMatchUtil.convertURIToRegex(excUrl);
                if (uri.matches(rex)) {
                    log.info("match Url: {}", excUrl);
                    filterChain.doFilter(request, response);
                    return;
                }
            }
            // 验证Referer中的domain与JWT中解析的domain一致
            String token = request.getHeader(HttpHeaders.AUTHORIZATION);
            token = token.replace(tokenHead, "").replace(" ", "");
            String refererDomain = request.getHeader("Referer").substring(7).split("\\.")[0];
            String schema = jwtTokenUtil.getSchemaFromToken(token);
            log.info("schema :{} , refererDomain : {}", schema, refererDomain);
            Assert.isTrue(refererDomain.equals(schema), "token错误");
            log.info("URL : {} ,method:{}", request.getPathInfo(), request.getMethod());
            filterChain.doFilter(request, response);

    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE + 1;
    }
}
